package org.agony2d.gpu.supportClasses.buffers {
	import flash.geom.Matrix;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import org.agony2d.gpu.supportClasses.textures.TextureProxy;
	
	import org.agony2d.core.agony_internal;
	
	use namespace agony_internal;
	
public class VertexCombine {
	
	public function VertexCombine() {
		m_bytes = new ByteArray
		m_bytes.endian = Endian.LITTLE_ENDIAN
	}
	
	[Inline]
	final agony_internal function setVertexCoords( width:int, height:int, matrix:Matrix ) : void {
		m_bytes.position = 0
		m_bytes.writeFloat(matrix.tx)
		m_bytes.writeFloat(matrix.ty)
		
		m_bytes.position = BYTES_TOTAL
		m_bytes.writeFloat(matrix.a * width + matrix.tx)
		m_bytes.writeFloat(matrix.b * width + matrix.ty)
		
		m_bytes.position = BYTES_TOTAL * 2
		m_bytes.writeFloat(matrix.c * height + matrix.tx)
		m_bytes.writeFloat(matrix.d * height + matrix.ty)
		
		m_bytes.position = BYTES_TOTAL * 3
		m_bytes.writeFloat(matrix.a * width  + matrix.c * height + matrix.tx)
		m_bytes.writeFloat(matrix.d * height + matrix.b * width  + matrix.ty)
	}
	
	[Inline]
	final agony_internal function setVertexCoordsFixed( width:int, height:int, matrix:Matrix ) : void {
		m_bytes.position = BYTES_TOTAL
		m_bytes.writeFloat(matrix.a * width + matrix.tx)
		m_bytes.writeFloat(matrix.b * width + matrix.ty)
		
		m_bytes.position = BYTES_TOTAL * 2
		m_bytes.writeFloat(matrix.c * height + matrix.tx)
		m_bytes.writeFloat(matrix.d * height + matrix.ty)
		
		m_bytes.position = BYTES_TOTAL * 3
		m_bytes.writeFloat(matrix.a * width  + matrix.c * height + matrix.tx)
		m_bytes.writeFloat(matrix.d * height + matrix.b * width  + matrix.ty)
	}
	
	[Inline]
	final agony_internal function setUV( tex:TextureProxy ) : void {
		// left top
		m_bytes.position = BYTES_UV_OFFSET
		m_bytes.writeFloat(tex.m_x / tex.m_fullWidth)
		m_bytes.writeFloat(tex.m_y / tex.m_fullHeight)
		
		// right top
		m_bytes.position = BYTES_TOTAL + BYTES_UV_OFFSET
		m_bytes.writeFloat((tex.m_x + tex.m_realityWidth) / tex.m_fullWidth)
		m_bytes.writeFloat(tex.m_y / tex.m_fullHeight)
		
		// left bottom
		m_bytes.position = BYTES_TOTAL * 2 + BYTES_UV_OFFSET
		m_bytes.writeFloat(tex.m_x / tex.m_fullWidth)
		m_bytes.writeFloat((tex.m_y + tex.m_realityHeight) / tex.m_fullHeight)
		
		// right bottom
		m_bytes.position = BYTES_TOTAL * 3 + BYTES_UV_OFFSET
		m_bytes.writeFloat((tex.m_x + tex.m_realityWidth) / tex.m_fullWidth)
		m_bytes.writeFloat((tex.m_y + tex.m_realityHeight) / tex.m_fullHeight)
	}
	
	[Inline]
	final agony_internal function setTint( color:uint ) : void {
		m_bytes.position = BYTES_COLOR_OFFSET
		m_bytes.writeUnsignedInt(color)
		
		m_bytes.position = BYTES_TOTAL * 1 + BYTES_COLOR_OFFSET
		m_bytes.writeUnsignedInt(color)
		
		m_bytes.position = BYTES_TOTAL * 2 + BYTES_COLOR_OFFSET
		m_bytes.writeUnsignedInt(color)
		
		m_bytes.position = BYTES_TOTAL * 3 + BYTES_COLOR_OFFSET
		m_bytes.writeUnsignedInt(color)
	}
	
	agony_internal function recycle() : void {
		cachedCombineList[cachedCombineLength++] = this
	}
	
	agony_internal static function NewVertexCombine() : VertexCombine {
		return (cachedCombineLength > 0 ? cachedCombineLength-- : 0) ? cachedCombineList.pop() : new VertexCombine
	}
	
	agony_internal static const BYTES_UV_OFFSET:int = 8
	agony_internal static const BYTES_COLOR_OFFSET:int = 16
	agony_internal static const BYTES_TOTAL:int = 20
		
	agony_internal static var cachedCombineList:Array = []
	agony_internal static var cachedCombineLength:int
	
	agony_internal var m_bytes:ByteArray
}
}